package com.stars.easyms.datasource.loadbalancer;

import com.stars.easyms.datasource.EasyMsDataSource;
import com.stars.easyms.datasource.EasyMsDataSourceSet;

import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom;

/**
 * <p>className: BestAvailableDataSourceLoadBalancer</p>
 * <p>description: 最可用模式数据源负载均衡器：最可用模式：选取当前最空闲的数据库进行操作，slave默认策略</p>
 *
 * @author guoguifang
 * @version 1.2.1
 * @date 2019-05-13 13:33
 */
final class BestAvailableDataSourceLoadBalancer implements DataSourceLoadBalancer {

    @Override
    public EasyMsDataSource getDataSource(EasyMsDataSourceSet easyMsDataSourceSet) {
        // 此算法比stream流的sorted排序算法效率高一倍
        TreeMap<Long, List<EasyMsDataSource>> sortedMap = new TreeMap<>();
        for (EasyMsDataSource easyMsDataSource : easyMsDataSourceSet) {
            Long currentExecuteCount = easyMsDataSource.getCurrentExecuteCount();
            List<EasyMsDataSource> subEasyMsDataSourceList = sortedMap.computeIfAbsent(currentExecuteCount, key -> new ArrayList<>());
            subEasyMsDataSourceList.add(easyMsDataSource);
        }
        // 如果有相同正在执行数量的数据源时使用随机选择的方式获取
        List<EasyMsDataSource> subEasyMsDataSourceList = sortedMap.firstEntry().getValue();
        int subEasyMsDataSourceCount = subEasyMsDataSourceList.size();
        if (subEasyMsDataSourceCount == 1) {
            return subEasyMsDataSourceList.get(0);
        }
        return subEasyMsDataSourceList.get(ThreadLocalRandom.current().nextInt(subEasyMsDataSourceCount));
    }
}